use std::{
    sync::{Arc, atomic::AtomicBool},
    time::Duration,
};
use tokio::sync::{Mutex, RwLock};
use crate::{student::Student, utils::RandomGen};

type Gallery = Arc<RwLock<crate::gallery::Gallery>>;
pub(crate) struct TeacherAssist {
    is_busy: Mutex<AtomicBool>,
    random: Mutex<RandomGen>,
    gallery: Gallery,
}

impl TeacherAssist {
    pub fn new(gallery: Gallery) -> Self {
        Self {
            is_busy: Mutex::new(AtomicBool::new(false)),
            random: Mutex::new(RandomGen::new(3..10)),
            gallery,
        }
    }
    pub async fn is_busy(&self) -> bool {
        self.is_busy
            .lock()
            .await
            .load(std::sync::atomic::Ordering::Relaxed)
    }
    pub async fn assist_student(&self, student: Arc<Student>) {
        self.assist_student_impl(student).await;
        loop {
            let first_chair_stu = self.gallery.write().await.get_first_used_chair();
            if let Some(student) = first_chair_stu {
                println!("从长廊的椅子上看到了学生:{}，准备辅导他", student.name());
                self.assist_student_impl(student).await;
            } else {
                println!("助教去休息了");
                break;
            }
        }
    }
    async fn assist_student_impl(&self, student: Arc<Student>) {
        *self.is_busy.lock().await.get_mut() = true;
        let random_assist_time = self.get_assist_time().await;
        println!("辅导学生：{} {}秒 开始", student.name(), random_assist_time);
        tokio::time::sleep(Duration::from_secs(random_assist_time as u64)).await;
        //todo:调用学生得一个方法，表示该学生接受辅导
        println!("辅导学生：{} {}秒 结束", student.name(), random_assist_time);
        *self.is_busy.lock().await.get_mut() = false;
    }

    async fn get_assist_time(&self) -> u8 {
        self.random
            .lock()
            .await
            .get_random_num()
            .map(|x| *x)
            .expect("failed to get time")
    }
}
